/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#ifndef __SINGLETON_H_
#define __SINGLETON_H_

#include <Types/vTypes.h>
#include "../../Macros/vMemoryMacros.h"

namespace Vendetta {

	/*! \class ISingleton
	 *   \brief A ISingleton class.
	 *
	 *    Singleton interface. Each singleton releasing is managed
	 *	  by SingletonManager.
	 */
	template <typename T> class vSingleton {
	public:
		/*! \brief Releases all resources used by this instance.
		*
		*  Clean all resources that are not need anymore.
		*
		*  \sa 	SingletonManager.
		*/
		static vVoid Release() { 
			if (mpSingleton) {
				delete mpSingleton;
				mpSingleton = 0;
			}
		}

		static T& Instance() {
			createIfNeeded();

			return *mpSingleton;
		}

		static T* InstancePtr() {
			createIfNeeded();

			return mpSingleton;
		}

	protected:
		vSingleton() { }
		virtual ~vSingleton() {
			if (mpSingleton == this) {
				mpSingleton = vNull;
			}
		}
		vSingleton(const vSingleton& singleton) { }
		vSingleton& operator=(const vSingleton& singleton) { return *this; }

	private:
		static vVoid createIfNeeded() {
			if (!mpSingleton) {
				mpSingleton = new T;

			}
		}

	protected:
		static T* mpSingleton;
	};
}

#endif		// __SINGLETON_H_